import * as kk from "kokomi.js";
import * as THREE from "three";
import type * as STDLIB from "three-stdlib"
import wind_vertex_shader from "./Shaders/CustomMaterial.vert.glsl"
import wind_fragment_shader from "./Shaders/CustomMaterial.frag.glsl"


export default class Wind extends kk.Component {

    gltf: STDLIB.GLTF;
    uj: kk.UniformInjector;
    mesh_material: kk.CustomShaderMaterial;
    wave_amplitude: number;
    boundingBox: THREE.Box3;

    constructor(base: kk.Base, gltf: STDLIB.GLTF, textureList:{}) {
        super( base );
        this.gltf = gltf;
        const uj = new kk.UniformInjector( this.base );
        this.uj = uj;

        // 计算模型的包围盒
        this.boundingBox = new THREE.Box3();
        this.boundingBox.setFromObject( this.gltf.scene );
        const boundsMin = this.boundingBox.min;
        const boundsMax = this.boundingBox.max;
        console.log( "*** Bounding ***", boundsMax, ", ",boundsMin );

        this.mesh_material = new kk.CustomShaderMaterial({
            baseMaterial: THREE.MeshBasicMaterial,
            vertexShader: wind_vertex_shader,
            fragmentShader: wind_fragment_shader,
            uniforms: {
                ...this.uj.shadertoyUniforms,
                // 参数
                uBoundsMin: { value: new THREE.Vector3( boundsMin.x, boundsMin.y, boundsMin.z ) },
                uBoundsMax: { value: new THREE.Vector3( boundsMax.x, boundsMax.y, boundsMax.z ) },
                iPercentX:  { value: 3.3 },
                iPercentY:  { value: 3.3 },
                uAmplitude: { value: 0.2 },
                // 纹理
                uv_mid:         {value: textureList["texture_mid"]},
                uv_out:         {value: textureList["texture_out"]},
                uv_head_tail:   {value: textureList["texture_head_tail"]},
                uv_sides:       {value: textureList["texture_sides"]},
            },
            side: THREE.DoubleSide,
            transparent: true,
            depthWrite: true,
            depthTest: true,
            blending: THREE.AdditiveBlending,
        });
        gltf.scene.traverse( (item)=>{
            if ( item instanceof THREE.Mesh ) {
                item.material = this.mesh_material;
            }
        } )
    }
                  
    updateMovement( delta: THREE.Vector2 ): void {
        // this.mesh_material.uniforms.iPercentX.value = delta.x / window.innerWidth * 100;
        // this.mesh_material.uniforms.iPercentY.value = delta.y / window.innerHeight * 100;
        this.mesh_material.uniforms.iPercentX.value = delta.x ;
        this.mesh_material.uniforms.iPercentY.value = delta.y ;
    }

    addExisting(): void {
        this.gltf.scene.scale.set( 1.0, 1.0, 1.0 );
        this.base.scene.add( this.gltf.scene );
    }

    update(time: number): void {
        this.uj.injectShadertoyUniforms( this.mesh_material.uniforms );
    }
}